package com.ah.shanxi_demo.service.impl;

import com.ah.shanxi_demo.common.enums.CommonEnum;
import com.ah.shanxi_demo.common.enums.PolicyCommonEnum;
import com.ah.shanxi_demo.param.result.ConvertBase64FileRO;
import com.ah.shanxi_demo.param.result.SXResult;
import com.ah.shanxi_demo.service.IFileService;
import jxl.Workbook;
import jxl.format.Colour;
import jxl.format.UnderlineStyle;
import jxl.write.*;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.lang.Boolean;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;

import static com.ah.shanxi_demo.common.Base64FileUtil.convertBase64;
import static com.ah.shanxi_demo.common.excel.ExcelType.*;

/**
 * @author Tao on 2020/9/15
 */
@Service
public class FileService implements IFileService {

    private static final Logger log = LoggerFactory.getLogger(FileService.class);

    @Override
    public Boolean downloadFile(String fileName, Integer fileType) {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletResponse response = requestAttributes.getResponse();
        HttpServletRequest request = requestAttributes.getRequest();

        //拼装文件名称
        CommonEnum fileEnum = CommonEnum.convertInt(fileType);
        String fileNameVirtual = fileName + fileEnum.getValue();

        // 下载本地文件
        String paths ="";
        if (CommonEnum.File_XLS.getKeyInt()==fileType){
            paths=creatExcelFile(fileNameVirtual, request);
        }
        try {
            // 读到流中
            InputStream inStream = new FileInputStream(paths);// 文件的存放路径
            // 设置输出的格式
            response.reset();
            response.addHeader("Content-Disposition", "attachment; filename=\"" + fileNameVirtual + "\"");
            // 循环取出流中的数据
            byte[] b = new byte[100];
            int len;
            while ((len = inStream.read(b)) > 0)
                response.getOutputStream().write(b, 0, len);
            inStream.close();
        } catch (FileNotFoundException e) {
            log.error("【FileService】【FileNotFoundException】fail:" + e.getMessage());
            return Boolean.FALSE;
        } catch (IOException e) {
            log.error("【FileService】【IOException】fail:" + e.getMessage());
            return Boolean.FALSE;
        }

        return Boolean.TRUE;
    }

    @Override
    public ConvertBase64FileRO convertBase64File(MultipartFile multipartFile) {
        ConvertBase64FileRO base64FileRO=new ConvertBase64FileRO();
        base64FileRO.setFileBase64(convertBase64(multipartFile));
        base64FileRO.setFileName(multipartFile.getOriginalFilename());
        return base64FileRO;
    }

    @Override
    public SXResult<Object> importExcel(MultipartFile file, String type) {
        try {
            org.apache.poi.ss.usermodel.Workbook wb = readExcel(file); // 获得excel文件对象workbook
            Sheet sheet = wb.getSheetAt(0); // 获取指定工作表<这里获取的是第一个>
            Object result;
            PolicyCommonEnum convert = PolicyCommonEnum.convert(type);

            switch (convert) {
                case POLICY_TYPE_1:
                    result = convert_policy_type1(sheet);
                    break;
                case POLICY_TYPE_2:
                    result = convert_policy_type2(sheet);
                    break;
                case POLICY_TYPE_3:
                    result = convert_policy_type3(sheet);
                    break;
                case POLICY_TYPE_4:
                    result = convert_policy_type4(sheet);
                    break;
                case POLICY_TYPE_5:
                    result = convert_policy_type5(sheet);
                    break;
                default:
                    result ="Import false";
                    break;
            }
            return SXResult.instance(result);

        } catch (IndexOutOfBoundsException e) {
            log.error("【FileService】【importExcel】fail:" + e.getMessage());
            return SXResult.instance(" 【importExcel】 false");
        }
    }

    public static String creatExcelFile(String filename, HttpServletRequest request) {

        String path = null;
        try {

            // 写到服务器上（这种测试过，在本地可以，放到linux服务器就不行）
            path = request.getSession().getServletContext().getRealPath("") + "/" + filename;

            // 写到服务器上
            //String path =  this.getClass().getClassLoader().getResource("").getPath()+"/"+filename;

            File name = new File(path);
            // 创建写工作簿对象
            WritableWorkbook workbook = Workbook.createWorkbook(name);
            // 工作表
            WritableSheet sheet = workbook.createSheet("sheet_" + filename, 0);
            // 设置字体;
            WritableFont font = new WritableFont(WritableFont.ARIAL, 14, WritableFont.BOLD, false, UnderlineStyle.NO_UNDERLINE, Colour.RED);

            WritableCellFormat cellFormat = new WritableCellFormat(font);
            // 设置背景颜色;
            cellFormat.setBackground(Colour.WHITE);
            // 设置边框;
            cellFormat.setBorder(Border.ALL, BorderLineStyle.DASH_DOT);
            // 设置文字居中对齐方式;
            cellFormat.setAlignment(Alignment.CENTRE);
            // 设置垂直居中;
            cellFormat.setVerticalAlignment(VerticalAlignment.CENTRE);
            // 分别给1,5,6列设置不同的宽度;
            sheet.setColumnView(0, 15);
            sheet.setColumnView(4, 60);
            sheet.setColumnView(5, 35);
            // 给sheet电子版中所有的列设置默认的列的宽度;
            sheet.getSettings().setDefaultColumnWidth(20);
            // 给sheet电子版中所有的行设置默认的高度，高度的单位是1/20个像素点,但设置这个貌似就不能自动换行了
            // sheet.getSettings().setDefaultRowHeight(30 * 20);
            // 设置自动换行;
            cellFormat.setWrap(true);

            //excel文件格式
            querySheet(sheet, cellFormat);

            workbook.write();
            //关闭流
            workbook.close();

        } catch (Throwable e) {
            log.error("【FileService】【creatExcelFile】fail:" + e.getMessage());
        }

        return path;
    }
    public static WritableSheet querySheet(WritableSheet sheet, WritableCellFormat cellFormat) {

        // 单元格
        Label label0 = new Label(0, 0, "ID", cellFormat);
        Label label1 = new Label(1, 0, "省", cellFormat);
        Label label2 = new Label(2, 0, "市", cellFormat);
        Label label3 = new Label(3, 0, "区", cellFormat);
        Label label4 = new Label(4, 0, "详细地址", cellFormat);
        Label label5 = new Label(5, 0, "创建时间", cellFormat);

        try {
            sheet.addCell(label0);
            sheet.addCell(label1);
            sheet.addCell(label2);
            sheet.addCell(label3);
            sheet.addCell(label4);
            sheet.addCell(label5);
        } catch (WriteException e) {
            log.error("【FileService】【querySheet】fail:" + e.getMessage());
        }
        return sheet;
    }



    /**
     * xls/xlsx都使用的Workbook
     */
    private static org.apache.poi.ss.usermodel.Workbook readExcel(MultipartFile file) {
        org.apache.poi.ss.usermodel.Workbook wb = null;
        if (file == null) {
            return null;
        }
        String extString = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        try {
            InputStream is = file.getInputStream();
            if (".xls".equals(extString)) {
                return wb = new HSSFWorkbook(is);
            } else if (".xlsx".equals(extString)) {
                return wb = new XSSFWorkbook(is);
            }
        } catch (IOException e) {
            log.error("【FileService】【readExcel】fail:" + e.getMessage());
        }
        return wb;

    }

    /**
     * format表格内容
     */
    public static String getCellFormatValue(Cell cell) {
        Object cellValue = "";

        if (cell != null) {

            switch (cell.getCellType()) {
                case 0: // 数字
                    //如果为时间格式的内容
                    if (HSSFDateUtil.isCellDateFormatted(cell)) {
                        //注：format格式 yyyy-MM-dd hh:mm:ss 中小时为12小时制，若要24小时制，则把小h变为H即可，yyyy-MM-dd HH:mm:ss
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                        cellValue = sdf.format(HSSFDateUtil.getJavaDate(cell.
                                getNumericCellValue())).toString();
                        break;
                    } else {
                        cellValue = cell.getNumericCellValue();
                    }
                    break;
                case 1: // 字符串
                    cellValue = cell.getStringCellValue();
                    break;
                case 4: // Boolean
                    cellValue = cell.getNumericCellValue();
                    break;
                case 2: // 公式
                    cellValue = cell.getCellFormula();
                    break;
                case 3: // 空值
                    cellValue = "";
                    break;
                case 5: // 故障
                    cellValue = cell.getErrorCellValue();
                    break;
                default:
                    cellValue = "";
                    break;
            }
        }
        if (cellValue.toString().endsWith(".0")) {
            String[] s = cellValue.toString().split("\\.");
            return s[0];
        }
        return cellValue.toString();
    }

    private static String getFloatStr1(String numberStr) {
        java.text.NumberFormat numberFormat = java.text.NumberFormat.getPercentInstance();
        numberFormat.setMaximumFractionDigits(1); //精确到3位。

        return numberFormat.format(Float.parseFloat(numberStr));
    }

    private String getFloatStr(String numberStr) {
        java.text.NumberFormat numberFormat = NumberFormat.getPercentInstance();
        numberFormat.setMaximumFractionDigits(2); //精确到3位。

        return numberFormat.format(Float.parseFloat(numberStr));
    }

}
